﻿using Core.Entities;
using Core.Enums;
using Core.Tools;
using Core.Writer;
using System;
using System.Collections.Generic;

namespace Core.ReadWriter
{
    [Serializable]
    public class TableReadWriter : BaseReadWriter
    {
        private readonly Type Type;
        private RWTypes InternalObjectType;

        private Table TableContent
        {
            get
            {
                return (Table)InternalContent;
            }
        }

        internal TableReadWriter(Type Type, object Content, RWSigns Sign) : base(Content, Sign)
        {
            this.Type = Type;
            InternalObjectType = RWTypes.Table;
        }

        public TableReadWriter() : base(new Table(), RWSigns.Property | RWSigns.ChangeType)
        {
            Type = typeof(Table);

            InternalObjectType = RWTypes.Table;
        }

        public TableReadWriter(Table Content, Type Type = null, RWSigns Sign = RWSigns.Property | RWSigns.ChangeType) : base(Content, Sign)
        {
            if (Content == null)
            {
                throw new NullReferenceException("Content");
            }

            if (Type == null)
            {
                Type = Content.GetType();
            }

            this.Type = Type;

            InternalObjectType = RWTypes.Table;
        }

        public override object this[string Name]
        {
            get
            {
                return AsGetValue(TableContent[Name]);
            }
            set
            {
                TableContent[Name] = AsSetValue(value);
            }
        }

        public override object this[int Index]
        {
            get
            {
                return AsGetValue(TableContent[Index]);
            }
            set
            {
                TableContent[Index] = AsSetValue(value);
            }
        }

        public override IEnumerable<string> Fields
        {
            get
            {
                return TableContent.Columns;
            }
        }

        public override int Count
        {
            get
            {
                return TableContent.ColumnsCount;
            }
        }

        public override RWTypes ObjectType
        {
            get
            {
                return InternalObjectType;
            }
            set
            {
                if (TableContent.RowsCount >= 2 && value != RWTypes.Table)
                {
                    throw new Exception("Cannot modify 'ObjectType' when the 'RowsCount' greater than 2");
                }

                InternalObjectType = value;
            }
        }

        public override void Add(string Name, object Value)
        {
            if (InternalObjectType == RWTypes.Array)
            {
                TableContent[TableContent.ColumnsCount] = AsSetValue(Value);
            }
            else
            {
                TableContent.Add(Name, AsSetValue(Value));
            }
        }

        public override void Next()
        {
            if (TableContent.RowsCount != 0 && InternalObjectType != RWTypes.Table)
            {
                throw new Exception("当 ObjectType 为 Array/Object 时只能添加一行数据。");
            }

            TableContent.Next();
        }

        public override bool Read()
        {
            return TableContent.Read();
        }

        public override void Reset()
        {
            TableContent.Reset();
        }

        public override bool TryGetValue(string Name, out object Value)
        {
            if (TableContent.TryGetValue(Name, out Value))
            {
                Value = AsGetValue(Value);

                return true;
            }

            Value = null;

            return false;
        }
    }
}